﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

// NotReviewedButNeeded
#pragma once

#include "GcmpDevService.h"
#include "LogType.h"
#include <fstream>
#include <tuple>
#include <map>

#pragma warning( push )
#pragma warning( disable : 4251 )

namespace gcmp
{
    // 记录管理器基类
    class GCMP_DEV_SERVICE_EXPORT LogBase
    {
    public:
        // 初始化。需要提供文件夹，文件名(不带编号部分)，文件拓展名（带'.'的后缀，例如".log")参数
        void Initialize(const std::wstring& folderPath, const std::wstring& preferredFileName, const std::wstring& fileExt);

        void AddExtraOutputPath(const std::wstring& folderPath, const std::wstring& preferredFileName, const std::wstring& fileExt);

        void DeleteExtraOutputPath(const std::wstring& folderPath, const std::wstring& preferredFileName, const std::wstring& fileExt);

        // 查询是否准备好
        bool IsReady() const;

        // 查询是否启用
        bool IsEnabled() const;

        // 获取缩进
        int GetIntentSize() const;

        // 设置缩进
        void SetIntentSize(int intentSize);

        // 获取文件夹
        const std::wstring& GetFolderPath() const;

        // 获取文件名（不带编号）
        const std::wstring& GetFileName() const;

        // 获取文件拓展名
        const std::wstring& GetFileExt() const;

        // 获取应用程序设定的Log文件夹
        static std::wstring GetAppLogsFolderPath();

        // 根据文件夹、文件名（不含编号）、拓展名（带.，例如".log"），查找可用的全路径名
        static std::wstring FindAvailablePath(const std::wstring& folder, const std::wstring& prefix, const std::wstring& ext);

    protected:
        LogBase(const std::wstring& appConfigKey);

        void LogLine(
            bool withTimestamp,
            bool commentTimestamp,
            bool withLogType,
            bool commentLogType,
            LogTypeOfLogManager logType,
            const std::wstring& text
            );
        void LogLine(
            const std::wstring& file,
            bool withTimestamp,
            bool commentTimestamp,
            bool withLogType,
            bool commentLogType,
            LogTypeOfLogManager logType,
            const std::wstring& text
            
        );

        virtual ~LogBase() = 0;

        static std::wstring MakeTimeStamp();

        /// \brief 日志的注释类型
        enum class CommentType : uint8_t
        {
            None                = 0,    ///< 没有
            SlashAsterisk       = 1,    ///< 斜杠和星号 /* */
            DoubleSlash         = 2,    ///< 双斜杠 //
            CommentTypeCount            ///< 个数
        };

        static std::wstring Comment(const std::wstring& text, CommentType commentType);

    private:
        std::wstring m_appConfigKey;
        int m_intentSize;
        bool m_isReady;

        std::wstring m_folderPath;
        std::wstring m_fileName;
        std::wstring m_fileExt;

        std::fstream m_fileStream;

        std::map<std::tuple<std::wstring, std::wstring, std::wstring>, OwnerPtr<std::fstream>> m_extraOutputPath;
    };
}

#pragma warning( pop )
